﻿using System;
using System.Collections.Concurrent;

namespace opentel.hub
{
    using opentel.hub.data;
    using SIPSorcery.SIP;

    internal class contactstore
    {
        internal ConcurrentDictionary<string, SIPAccountInfo> _accounts = new ConcurrentDictionary<string, SIPAccountInfo>();
        internal ConcurrentDictionary<string, string> _callids = new ConcurrentDictionary<string, string>();
        internal void Add(string user, SIPAccountInfo binding)
        {
            if (_accounts.ContainsKey(user)) _accounts.TryRemove(user, out var removed);
            if (_callids.ContainsKey(binding.CallId)) _callids.TryRemove(binding.CallId, out var removed);

            _accounts.TryAdd(user, binding);
            _callids.TryAdd(binding.CallId, user);
        }
        internal bool Remove(string user)
        {
            SIPAccountInfo removed = SIPAccountInfo.DEFAULT;
            if (_accounts.ContainsKey(user)) _accounts.TryRemove(user, out removed);

            if (removed == null) return false;
            if (_callids.ContainsKey(removed.CallId)) _callids.TryRemove(user, out var removed2);
            return true;
        }
        internal bool RemoveByCallid(string callid)
        {
            var removed = string.Empty;
            if (_callids.ContainsKey(callid)) _callids.TryRemove(callid, out removed);
            if (string.IsNullOrEmpty(removed)) return false;
            return Remove(removed);
        }
        internal SIPAccountInfo Take(string user)
        {
            SIPAccountInfo binding = SIPAccountInfo.DEFAULT;
            if (_accounts.ContainsKey(user)) _accounts.TryGetValue(user, out binding);
            return binding;
        }
        internal SIPAccountInfo FindByUser(string user)
        {
            foreach (var account in _accounts.Values) if (account.RegisteredContact.User == user) return account;
            return SIPAccountInfo.DEFAULT;
        }
        internal SIPAccountInfo FindFrom(SIPRequest req)
        {
            var from = FindByUser(req.Header.From.FromURI.User);
            if (from != null && from.status == AccountStatus.UnKnown) from.status = AccountStatus.Free;
            return from;
        }
        internal SIPAccountInfo FindTo(SIPRequest req)
        {
            var to = FindByUser(req.URI.User);
            if (to != null && to.status == AccountStatus.UnKnown) to.status = AccountStatus.Free;
            return to;
        }
    }
}
